<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { configService } from '../services/configService'
import { networkSurveyService } from '../services/networkSurveyService'

type Task = {
  id: number
  name: string
  description: string
  startIp: string           // 起始IP
  endIp: string             // 终止IP
  startPort: number         // 统一的起始端口
  endPort: number           // 统一的结束端口
  createdAt: string
  status: 'pending' | 'submitting' | 'submitted' | 'error'  // pending: 未提交, submitting: 提交中, submitted: 已提交, error: 错误
  taskId?: string           // 后端返回的任务ID
  errorMessage?: string
}

const tasks = ref<Task[]>([])
const showDialog = ref(false)
const configLoaded = ref(false)
const serverInfo = ref('')
const detailTaskId = ref<number | null>(null)

const formStartIp = ref('')                  // 起始IP
const formEndIp = ref('')                    // 终止IP
const formPacketCount = ref<number | null>(10)  // 发包数量，默认值为10

// 状态持久化相关
const STORAGE_KEY = 'network-survey-state'

// 保存状态到localStorage
function saveState() {
  const state = {
    tasks: tasks.value,
    detailTaskId: detailTaskId.value
  }
  
  try {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(state))
    console.log('实网节点测绘状态已保存到localStorage')
  } catch (error) {
    console.error('保存状态失败:', error)
  }
}

// 从localStorage恢复状态
function loadState() {
  try {
    const savedState = localStorage.getItem(STORAGE_KEY)
    if (!savedState) return false
    
    const state = JSON.parse(savedState)
    
    // 恢复数据
    if (state.tasks) tasks.value = state.tasks
    if (state.detailTaskId !== undefined) detailTaskId.value = state.detailTaskId
    
    console.log('实网节点测绘状态已从localStorage恢复')
    return true
  } catch (error) {
    console.error('恢复状态失败:', error)
    return false
  }
}

// 自动保存机制
let saveTimer: number | null = null

function autoSave() {
  if (saveTimer) {
    clearTimeout(saveTimer)
  }
  saveTimer = setTimeout(() => {
    saveState()
    saveTimer = null
  }, 1000) // 1秒后保存，避免频繁保存
}

// 监听状态变化，触发自动保存
watch([tasks, detailTaskId], autoSave, { deep: true })

/**
 * 将IP地址转换为数字
 */
function ipToNumber(ip: string): number {
  const parts = ip.split('.').map(Number)
  return parts[0] * 256 * 256 * 256 + parts[1] * 256 * 256 + parts[2] * 256 + parts[3]
}

/**
 * 将数字转换为IP地址
 */
function numberToIp(num: number): string {
  const part1 = Math.floor(num / (256 * 256 * 256))
  num %= 256 * 256 * 256
  const part2 = Math.floor(num / (256 * 256))
  num %= 256 * 256
  const part3 = Math.floor(num / 256)
  const part4 = num % 256
  return `${part1}.${part2}.${part3}.${part4}`
}

/**
 * 验证IP地址格式
 */
function isValidIp(ip: string): boolean {
  const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/
  if (!ipRegex.test(ip)) return false
  
  const parts = ip.split('.').map(Number)
  return parts.every(part => part >= 0 && part <= 255)
}


// 加载配置
async function loadConfiguration() {
  try {
    const config = await configService.getNetworkSurveyConfig()
    serverInfo.value = `${config.protocol}://${config.targetHost}:${config.targetPort}`
    configLoaded.value = true
    console.log('网络扫描配置加载成功:', config)
  } catch (error) {
    console.error('配置加载失败:', error)
    serverInfo.value = '配置加载失败'
  }
}

function openCreate() {
  formStartIp.value = ''
  formEndIp.value = ''
  formPacketCount.value = 10  // 重置为默认值
  showDialog.value = true
}

// 自动生成任务名
function generateTaskName(): string {
  const now = new Date()
  const timeString = now.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false
  }).replace(/\//g, '-')
  return `扫描任务-${timeString}`
}

// 自动生成任务描述
function generateTaskDescription(taskName: string, startIp: string, endIp: string, startPort: number, endPort: number): string {
  const now = new Date()
  const timeString = now.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false
  }).replace(/\//g, '-')
  return `任务名：${taskName}\n创建时间：${timeString}\nIP范围：${startIp} - ${endIp}\n端口范围：${startPort}-${endPort}`
}


async function submitTask() {
  if (!formStartIp.value.trim()) {
    alert('请输入起始IP')
    return
  }

  if (!formEndIp.value.trim()) {
    alert('请输入终止IP')
    return
  }

  // 验证IP格式
  if (!isValidIp(formStartIp.value.trim())) {
    alert('起始IP格式错误')
    return
  }

  if (!isValidIp(formEndIp.value.trim())) {
    alert('终止IP格式错误')
    return
  }

  // 验证起始IP不能大于终止IP
  const startNum = ipToNumber(formStartIp.value.trim())
  const endNum = ipToNumber(formEndIp.value.trim())
  if (startNum > endNum) {
    alert('起始IP不能大于终止IP')
    return
  }

  if (formPacketCount.value === null || formPacketCount.value < 1) {
    alert('请输入有效的发包数量（正整数）')
    return
  }

  // 计算随机端口范围
  // 起始端口：从 10000 ~ (60000 - 用户输入的值) 中随机挑选
  const maxStartPort = 60000 - formPacketCount.value
  if (maxStartPort < 10000) {
    alert(`发包数量过大，最大允许值为 ${60000 - 10000}`)
    return
  }
  
  const randomStartPort = Math.floor(Math.random() * (maxStartPort - 10000 + 1)) + 10000
  const calculatedEndPort = randomStartPort + formPacketCount.value

  // 自动生成任务名和描述
  const taskName = generateTaskName()
  const startIp = formStartIp.value.trim()
  const endIp = formEndIp.value.trim()
  const taskDescription = generateTaskDescription(taskName, startIp, endIp, randomStartPort, calculatedEndPort)

  const newTask: Task = {
    id: Date.now(),
    name: taskName,
    description: taskDescription,
    startIp: startIp,
    endIp: endIp,
    startPort: randomStartPort,
    endPort: calculatedEndPort,
    createdAt: new Date().toLocaleString(),
    status: 'pending'
  }

  tasks.value.unshift(newTask)
  showDialog.value = false

  // 创建后不立即提交，等待用户点击"提交扫描"按钮
}

function toggleDetail(taskId: number) {
  detailTaskId.value = detailTaskId.value === taskId ? null : taskId
}

function deleteTask(taskId: number) {
  if (confirm('确定要删除这个任务吗？')) {
    const index = tasks.value.findIndex(t => t.id === taskId)
    if (index >= 0) {
      tasks.value.splice(index, 1)
    }
  }
}

function getStatusColor(status: string): string {
  switch (status) {
    case 'pending': return '#6b7280'
    case 'submitting': return '#f59e0b'
    case 'submitted': return '#10b981'
    case 'error': return '#ef4444'
    default: return '#6b7280'
  }
}

function getStatusLabel(status: string): string {
  switch (status) {
    case 'pending': return '未提交'
    case 'submitting': return '提交中'
    case 'submitted': return '已提交'
    case 'error': return '错误'
    default: return '未知'
  }
}

async function sendScanTask(task: Task) {
  if (task.status === 'submitting') {
    return
  }

  if (!configLoaded.value) {
    alert('配置未加载，无法提交任务')
    return
  }

  task.status = 'submitting'
  task.errorMessage = undefined

  try {
    if (!task.startIp || !task.endIp || task.startPort === undefined || task.endPort === undefined) {
      throw new Error('扫描任务缺少必要信息')
    }

    const scanTaskData = {
      taskName: task.name,
      description: task.description,
      startIp: task.startIp,
      endIp: task.endIp,
      startPort: task.startPort,
      endPort: task.endPort,
      timestamp: new Date().toISOString()
    }

    const response = await networkSurveyService.submitScanTask(scanTaskData)

    if (response.success) {
      task.status = 'submitted'
      task.taskId = response.taskId
      alert(`✅ 扫描任务提交成功！\n\n任务ID: ${response.taskId}\n任务名称: ${task.name}\nIP范围: ${task.startIp} - ${task.endIp}\n端口范围: ${task.startPort}-${task.endPort}`)
      console.log('扫描任务提交成功，后端响应:', response)
    } else {
      task.status = 'error'
      task.errorMessage = response.message || '提交失败'
      alert(`❌ 扫描任务提交失败：${response.message}`)
      console.error('扫描任务提交失败:', response)
    }
  } catch (error) {
    task.status = 'error'
    task.errorMessage = error instanceof Error ? error.message : '网络错误'
    alert(`❌ 任务提交失败：${task.errorMessage}`)
    console.error('任务提交失败:', error)
  }
}


onMounted(async () => {
  // 恢复状态
  loadState()
  
  // 加载配置文件
  await loadConfiguration()
})
</script>

<template>
  <div class="survey-layout">
    <!-- 主要内容区域 -->
    <main class="survey-main">
      <!-- 任务列表区域 -->
      <section class="task-section">
        <div class="section-header">
          <div class="section-title">
            <h2>任务列表</h2>
            <div class="task-count">{{ tasks.length }} 个任务</div>
          </div>
          <div class="header-buttons">
            <button class="create-task-btn" @click="openCreate">
              添加扫描任务
            </button>
          </div>
        </div>

        <!-- 空状态 -->
        <div v-if="tasks.length === 0" class="empty-state">
          <div class="empty-icon">🔍</div>
          <div class="empty-title">暂无扫描任务</div>
          <div class="empty-desc">点击"添加扫描任务"开始您的第一个网络扫描</div>
        </div>

        <!-- 任务列表 -->
        <div v-else class="task-list">
          <div v-for="t in tasks" :key="t.id" class="task-card">
            <div class="task-header">
              <div class="task-info">
                <div class="task-main-info">
                  <h3 class="task-name">{{ t.name }}</h3>
                  <div class="task-meta">
                    <span class="status-badge" :style="{ background: getStatusColor(t.status) }">
                      {{ getStatusLabel(t.status) }}
                    </span>
                    <span class="task-time">{{ t.createdAt }}</span>
                  </div>
                </div>
              </div>
              <div class="task-actions">
                <button 
                  v-if="t.status === 'pending' || t.status === 'error'" 
                  class="action-btn submit-btn" 
                  @click.stop="sendScanTask(t)"
                  :disabled="!configLoaded"
                >
                  <span class="btn-icon">📤</span>
                  <span>提交扫描</span>
                </button>
                <button class="action-btn detail-btn" @click="toggleDetail(t.id)">
                  <span class="btn-icon">{{ detailTaskId === t.id ? '🔽' : '🔍' }}</span>
                  <span>{{ detailTaskId === t.id ? '收起' : '详情' }}</span>
                </button>
                <button class="action-btn delete-btn" @click.stop="deleteTask(t.id)">
                  <span class="btn-icon">🗑️</span>
                </button>
              </div>
            </div>

            <div v-if="detailTaskId === t.id" class="task-detail">
              <div class="detail-section">
                <div class="detail-label">任务描述</div>
                <div class="detail-content">
                  <p v-if="t.description" class="description">{{ t.description }}</p>
                  <p v-else class="muted">无描述</p>
                </div>
              </div>
              
              <div v-if="t.taskId" class="detail-section">
                <div class="detail-label">任务ID</div>
                <div class="detail-content">
                  <code class="task-id">{{ t.taskId }}</code>
                </div>
              </div>
              
              <div v-if="t.errorMessage" class="detail-section">
                <div class="detail-label">错误信息</div>
                <div class="detail-content">
                  <div class="error-message">{{ t.errorMessage }}</div>
                </div>
              </div>
              
              <div class="detail-section">
                <div class="detail-label">端口范围</div>
                <div class="detail-content">
                  <div class="port-range">
                    <code>{{ t.startPort }} - {{ t.endPort }}</code>
                  </div>
                </div>
              </div>
              
              <div class="detail-section">
                <div class="detail-label">IP范围</div>
                <div class="detail-content">
                  <div class="ip-range">
                    <code>{{ t.startIp }} - {{ t.endIp }}</code>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>

    </main>

    <!-- 创建任务对话框 -->
    <div v-if="showDialog" class="dialog-mask" @click.self="showDialog = false">
      <div class="dialog">
        <div class="dialog-header">
          <h3>添加扫描任务</h3>
          <div class="dialog-subtitle">配置网络扫描参数</div>
        </div>
        <div class="dialog-content">
          <div class="form-row">
            <label>IP范围</label>
            <div class="ip-range-editor">
              <input 
                v-model="formStartIp" 
                placeholder="起始IP，例如：1.0.0.0"
                class="ip-input"
              />
              <span class="separator">-</span>
              <input 
                v-model="formEndIp" 
                placeholder="终止IP，例如：2.255.255.255"
                class="ip-input"
              />
            </div>
            <div class="input-hint">请输入起始IP和终止IP，起始IP不能大于终止IP</div>
          </div>
          <div class="form-row">
            <label>前后端架构：发包数量</label>
            <input 
              type="number" 
              v-model.number="formPacketCount" 
              placeholder="请输入发包数量" 
              min="1"
              class="packet-count-input"
            />
          </div>
        </div>
        <div class="dialog-actions">
          <button class="btn-cancel" @click="showDialog = false">取消</button>
          <button class="btn-confirm" @click="submitTask">创建任务</button>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
/* ================= 整体布局 ================= */

.survey-layout {
  min-height: 100%;
  padding: 24px 24px 32px;
  background: radial-gradient(circle at 0 0, #e0f2fe 0, #eef2ff 32%, #f9fafb 100%);
  box-sizing: border-box;
}

.survey-main {
  max-width: 1320px;
  margin: 0 auto;
  width: 100%;
  box-sizing: border-box;
}

/* ================= 任务区域外框 ================= */

.task-section {
  background: #ffffff;
  border-radius: 24px;
  box-shadow: 0 18px 45px rgba(15, 23, 42, 0.06);
  overflow: hidden;
  border: 1px solid rgba(148, 163, 184, 0.15);
}

/* 顶部标题行 */

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 32px;
  background: linear-gradient(135deg, #f9fafb 0%, #eef2ff 40%, #e0f2fe 100%);
  border-bottom: 1px solid #e2e8f0;
}

.section-title {
  display: flex;
  align-items: center;
  gap: 12px;
}

.section-title h2 {
  font-size: 20px;
  font-weight: 600;
  color: #0f172a;
  margin: 0;
}

.task-count {
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  color: #4f46e5;
  background: rgba(129, 140, 248, 0.12);
}

/* 右侧按钮区 */

.header-buttons {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* 统一新增任务按钮样式，贴合首页“全部刷新”样式 */

.create-task-btn,
.create-coarse-grained-btn {
  border: none;
  outline: none;
  cursor: pointer;
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 500;
  color: #ffffff;
  background: linear-gradient(135deg, #6366f1 0%, #4f46e5 45%, #7c3aed 100%);
  box-shadow: 0 10px 25px rgba(99, 102, 241, 0.35);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  white-space: nowrap;
  transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}

.create-task-btn:hover,
.create-coarse-grained-btn:hover {
  transform: translateY(-1px);
  filter: brightness(1.03);
  box-shadow: 0 14px 32px rgba(79, 70, 229, 0.45);
}

.create-task-btn:active,
.create-coarse-grained-btn:active {
  transform: translateY(0);
  box-shadow: 0 8px 18px rgba(79, 70, 229, 0.35);
}

.create-task-btn:disabled,
.create-coarse-grained-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  box-shadow: none;
}

/* 如果你还有 refresh-btn，顺便统一一下风格 */

.refresh-btn {
  border: none;
  padding: 10px 16px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 500;
  color: #ffffff;
  background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
  box-shadow: 0 10px 24px rgba(37, 99, 235, 0.35);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}

.refresh-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  filter: brightness(1.03);
  box-shadow: 0 14px 30px rgba(37, 99, 235, 0.45);
}

.refresh-btn:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: 0 8px 18px rgba(37, 99, 235, 0.35);
}

.refresh-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  box-shadow: none;
}

.btn-icon {
  font-size: 16px;
}

/* ================= 空状态 ================= */

.empty-state {
  padding: 72px 40px 80px;
  text-align: center;
  color: #64748b;
}

.empty-icon {
  font-size: 40px;
  margin-bottom: 16px;
  opacity: 0.7;
}

.empty-title {
  font-size: 18px;
  font-weight: 600;
  color: #0f172a;
  margin-bottom: 8px;
}

.empty-desc {
  font-size: 14px;
  color: #6b7280;
}

/* ================= 任务列表 & 卡片 ================= */

.task-list {
  padding: 20px 20px 24px;
  box-sizing: border-box;
}

.task-card {
  margin: 0 4px 16px;
  border-radius: 18px;
  background: radial-gradient(circle at 0 0, #eef2ff 0, #f9fafb 35%, #ffffff 100%);
  border: 1px solid rgba(148, 163, 184, 0.32);
  box-shadow: 0 10px 28px rgba(15, 23, 42, 0.08);
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
  overflow: hidden;
}

.task-card:last-child {
  margin-bottom: 0;
}

/* 已提交任务在左边加一条色条更显眼 */
.task-card::before {
  content: '';
  display: block;
  position: absolute;
}

.task-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 16px 40px rgba(15, 23, 42, 0.12);
}

/* 头部 */

.task-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding: 18px 24px 16px;
  box-sizing: border-box;
}

.task-info {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  flex: 1;
  min-width: 0;
}

.task-main-info {
  flex: 1;
  min-width: 0;
}

.task-name {
  font-size: 17px;
  font-weight: 600;
  color: #0f172a;
  margin: 0 0 6px;
  word-break: break-word;
}

.task-meta {
  display: flex;
  align-items: center;
  gap: 10px;
}

.status-badge {
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  color: #ffffff;
}

/* 让状态颜色更柔和：用背景色 + 半透明 */

.status-badge[style*="#6b7280"] {
  background: linear-gradient(135deg, #6b7280 0%, #4b5563 100%);
}
.status-badge[style*="#f59e0b"] {
  background: linear-gradient(135deg, #f59e0b 0%, #ea580c 100%);
}
.status-badge[style*="#10b981"] {
  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
}
.status-badge[style*="#ef4444"] {
  background: linear-gradient(135deg, #ef4444 0%, #b91c1c 100%);
}

.task-time {
  font-size: 13px;
  color: #6b7280;
}

/* 右侧按钮 */

.task-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  flex-wrap: wrap;
}

.action-btn {
  border-radius: 999px;
  padding: 7px 11px;
  font-size: 12px;
  font-weight: 500;
  border: 1px solid #e2e8f0;
  background: #ffffff;
  color: #475569;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease,
    transform 0.15s ease;
}

.action-btn:hover:not(:disabled) {
  background: #f8fafc;
  border-color: #cbd5e1;
  box-shadow: 0 4px 10px rgba(15, 23, 42, 0.08);
  transform: translateY(-1px);
}

.action-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  box-shadow: none;
}

/* 提交按钮更突出 */

.submit-btn {
  border: none;
  color: #ffffff;
  background: linear-gradient(135deg, #10b981 0%, #16a34a 45%, #22c55e 100%);
  box-shadow: 0 8px 18px rgba(34, 197, 94, 0.35);
}

.submit-btn:hover:not(:disabled) {
  background: linear-gradient(135deg, #059669 0%, #15803d 50%, #22c55e 100%);
  box-shadow: 0 12px 26px rgba(34, 197, 94, 0.45);
}

/* 删除按钮警示色 */

.delete-btn:hover:not(:disabled) {
  background: #fef2f2;
  border-color: #fecaca;
  color: #b91c1c;
}

/* ================= 任务详情（折叠区域） ================= */

.task-detail {
  padding: 0 24px 18px;
  border-top: 1px dashed #e2e8f0;
  background: linear-gradient(180deg, rgba(248, 250, 252, 0.9), #ffffff);
}

.detail-section {
  margin-top: 16px;
}

.detail-label {
  font-size: 13px;
  font-weight: 600;
  color: #475569;
  margin-bottom: 6px;
}

.detail-content {
  font-size: 14px;
  color: #0f172a;
}

.description {
  margin: 0;
  line-height: 1.6;
  white-space: pre-line;
}

.muted {
  color: #94a3b8;
  font-style: italic;
}

.task-id {
  display: inline-block;
  padding: 6px 10px;
  border-radius: 8px;
  background: #f9fafb;
  border: 1px solid #e2e8f0;
  font-size: 13px;
  font-family: 'SFMono-Regular', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New',
    monospace;
}

.error-message {
  padding: 10px 12px;
  border-radius: 10px;
  background: #fef2f2;
  border-left: 3px solid #dc2626;
  font-size: 13px;
  color: #b91c1c;
}

.port-range {
  display: inline-block;
  padding: 6px 10px;
  border-radius: 8px;
  background: #f9fafb;
  border: 1px solid #e2e8f0;
}

.port-range code,
.ip-range code {
  font-family: 'SFMono-Regular', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New',
    monospace;
  font-size: 13px;
  color: #0f172a;
}

.ip-range {
  display: inline-block;
  padding: 6px 10px;
  border-radius: 8px;
  background: #f9fafb;
  border: 1px solid #e2e8f0;
}

/* ================= 对话框 ================= */

.dialog-mask {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(4px);
  z-index: 1000;
}

.dialog {
  width: 700px;
  max-width: calc(100vw - 64px);
  max-height: 80vh;
  background: #ffffff;
  border-radius: 20px;
  box-shadow: 0 24px 60px rgba(15, 23, 42, 0.3);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.dialog-header {
  padding: 20px 28px 14px;
  background: linear-gradient(135deg, #eef2ff 0%, #e0f2fe 50%, #f9fafb 100%);
  border-bottom: 1px solid #e2e8f0;
}

.dialog-header h3 {
  margin: 0 0 4px;
  font-size: 18px;
  font-weight: 600;
  color: #0f172a;
}

.dialog-subtitle {
  font-size: 13px;
  color: #64748b;
}

.dialog-content {
  padding: 20px 28px;
  flex: 1;
  overflow-y: auto;
}

.form-row {
  margin-bottom: 18px;
}

.form-row label {
  display: block;
  font-size: 14px;
  font-weight: 500;
  color: #111827;
  margin-bottom: 6px;
}

input,
textarea {
  width: 100%;
  border-radius: 10px;
  border: 1px solid #d1d5db;
  padding: 10px 14px;
  font-size: 14px;
  box-sizing: border-box;
  background-color: #ffffff;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

input:focus,
textarea:focus {
  outline: none;
  border-color: #6366f1;
  box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.18);
}

textarea {
  min-height: 80px;
  resize: vertical;
}

.ip-range-editor {
  display: flex;
  align-items: center;
  gap: 10px;
}

.ip-input {
  flex: 1;
  font-family: 'SFMono-Regular', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New',
    monospace;
}

.ip-range-editor .separator {
  flex-shrink: 0;
  font-weight: 600;
  font-size: 18px;
  color: #9ca3af;
}

.input-hint {
  margin-top: 6px;
  font-size: 12px;
  color: #6b7280;
}

.packet-count-input {
  width: 180px;
}

.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 14px 28px 18px;
  background: #f9fafb;
  border-top: 1px solid #e2e8f0;
}

.btn-cancel {
  padding: 8px 18px;
  border-radius: 999px;
  border: 1px solid #d1d5db;
  background: #ffffff;
  color: #374151;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.btn-cancel:hover {
  background: #f3f4f6;
  border-color: #9ca3af;
}

.btn-confirm {
  padding: 8px 20px;
  border-radius: 999px;
  border: none;
  font-size: 14px;
  font-weight: 500;
  color: #ffffff;
  cursor: pointer;
  background: linear-gradient(135deg, #6366f1 0%, #4f46e5 45%, #7c3aed 100%);
  box-shadow: 0 10px 24px rgba(99, 102, 241, 0.35);
  transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}

.btn-confirm:hover {
  transform: translateY(-1px);
  filter: brightness(1.03);
  box-shadow: 0 14px 32px rgba(79, 70, 229, 0.45);
}

.btn-confirm:active {
  transform: translateY(0);
  box-shadow: 0 8px 18px rgba(79, 70, 229, 0.35);
}
</style>